﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using NumberProject;


namespace SilverlightCalculator
{
    public partial class KalkulatorControl : UserControl
	{

        #region Private Enumerations

        private enum CalculatorOperation
        { None, Add, Subtract, Multiply, Divide }

        #endregion

        #region Fields


        private Number firstNumber = new Number(0);
        private Number currentNumber = new Number(0);

        private CalculatorOperation currentOperation = CalculatorOperation.None;

        private bool isOperationButtonPressed = false;
        private bool isFloatButtonPressed = false;
        private bool isEnteringSecondNumber = false;
        private bool isCalculationDone = false;

        #endregion

        public KalkulatorControl()
        {
            // Required to initialize variables
            InitializeComponent();
        }

        private void DigitButton_Click(object sender, MouseButtonEventArgs e)
        {
            this.Focus();

            TextBlock txt = sender as TextBlock;
            if (txt != null)
            {
                OnDigitButtonPressed(Convert.ToInt16(txt.Tag));
            }
        }

        private void OperationButton_Click(object sender, MouseButtonEventArgs e)
        {
            this.Focus();

            TextBlock txt = sender as TextBlock;
            if (txt != null && txt.Tag is CalculatorOperation)
            {
                OnOperationButtonPressed((CalculatorOperation)txt.Tag);
            }
        }

        private void EqualsButton_Click(object sender, MouseButtonEventArgs e)
        {
            this.Focus();

            OnEqualsButtonPressed();
        }

        private void ClearButton_Click(object sender, MouseButtonEventArgs e)
        {
            this.Focus();

            OnClearButtonPressed();
        }

        private void FloatButton_Click(object sender, MouseButtonEventArgs e)
        {
            this.Focus();

            OnFloatButtonPressed();
        }

        private void NegateButton_Click(object sender, MouseButtonEventArgs e)
        {
            this.Focus();

            OnNegateButtonPressed();
        }

        #region Private Methods

        private void OnValueChanged()
        {
            ScreenTextBlock.Text = currentNumber.ToString();
        }

        private void OnDigitButtonPressed(int digit)
        {
            if (isOperationButtonPressed)
            {
                isOperationButtonPressed = false;
                isCalculationDone = false;
                isFloatButtonPressed = false;
                isEnteringSecondNumber = true;
                firstNumber = new Number(currentNumber);
                currentNumber = new Number(digit);
            }
            else if ((currentNumber == 0 && currentNumber.DigitsCount == 1 && !isFloatButtonPressed)
                     || isCalculationDone)
            {
                isCalculationDone = false;
                isFloatButtonPressed = false;
                currentNumber = new Number(digit);
            }
            else
            {
                if (isFloatButtonPressed)
                {
                    isFloatButtonPressed = false;
                    currentNumber = Number.AppendLastDigit(currentNumber, digit, true);
                }
                else
                {
                    currentNumber = Number.AppendLastDigit(currentNumber, digit);
                }
            }
            OnValueChanged();
        }

        private void OnOperationButtonPressed(CalculatorOperation operation)
        {
            if (isEnteringSecondNumber)
            {
                OnEqualsButtonPressed();
            }

            currentOperation = operation;
            isOperationButtonPressed = true;
            isFloatButtonPressed = false;
        }

        private void OnEqualsButtonPressed()
        {
            if (!(currentOperation == CalculatorOperation.None || isOperationButtonPressed == true))
            {
                switch (currentOperation)
                {
                    case CalculatorOperation.Add:
                        currentNumber += firstNumber;
                        break;
                    case CalculatorOperation.Subtract:
                        currentNumber = firstNumber - currentNumber;
                        break;
                    case CalculatorOperation.Multiply:
                        currentNumber *= firstNumber;
                        break;
                    case CalculatorOperation.Divide:
                        if (currentNumber != 0)
                        {
                            currentNumber = firstNumber / currentNumber;
                        }
                        else
                        {
                            ScreenTextBlock.Text = "Can't divide by zero.";
                        }
                        break;
                    default:
                        throw new NotSupportedException(String.Format("Unsupported operation: {0}",
                            Enum.GetName(typeof(CalculatorOperation), currentOperation)));
                }
                if (!(currentOperation == CalculatorOperation.Divide && currentNumber == 0))
                {
                    OnValueChanged();
                }
                currentOperation = CalculatorOperation.None;
                isCalculationDone = true;
            }
        }

        private void OnNegateButtonPressed()
        {
            currentNumber = -currentNumber;
            OnValueChanged();
        }

        private void OnClearButtonPressed()
        {
            firstNumber = new Number(0);
            currentNumber = new Number(0);
            isOperationButtonPressed = false;
            isFloatButtonPressed = false;
            isEnteringSecondNumber = false;
            isCalculationDone = false;
            currentOperation = CalculatorOperation.None;
            OnValueChanged();
        }

        private void OnFloatButtonPressed()
        {
            isFloatButtonPressed = true;
        }

        #endregion

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            btn1.txtDigit.Text = "1";
            btn1.txtDigit.Tag = "1";
            btn1.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(DigitButton_Click);

            btn2.txtDigit.Text = "2";
            btn2.txtDigit.Tag = "2";
            btn2.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(DigitButton_Click);

            btn3.txtDigit.Text = "3";
            btn3.txtDigit.Tag = "3";
            btn3.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(DigitButton_Click);

            btn4.txtDigit.Text = "4";
            btn4.txtDigit.Tag = "4";
            btn4.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(DigitButton_Click);

            btn5.txtDigit.Text = "5";
            btn5.txtDigit.Tag = "5";
            btn5.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(DigitButton_Click);

            btn6.txtDigit.Text = "6";
            btn6.txtDigit.Tag = "6";
            btn6.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(DigitButton_Click);

            btn7.txtDigit.Text = "7";
            btn7.txtDigit.Tag = "7";
            btn7.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(DigitButton_Click);

            btn8.txtDigit.Text = "8";
            btn8.txtDigit.Tag = "8";
            btn8.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(DigitButton_Click);

            btn9.txtDigit.Text = "9";
            btn9.txtDigit.Tag = "9";
            btn9.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(DigitButton_Click);

            btn0.txtDigit.Text = "0";
            btn0.txtDigit.Tag = "0";
            btn0.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(DigitButton_Click);

            btnDot.txtDigit.Text = ".";
            btnDot.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(FloatButton_Click);

            btnClear.txtDigit.Text = "C";
            btnClear.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(ClearButton_Click);

            btnEqual.txtDigit.Text = "=";
            btnEqual.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(EqualsButton_Click);

            btnMinus.txtDigit.Text = "–";
            btnMinus.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(OperationButton_Click);

            btnPlus.txtDigit.Text = "+";
            btnPlus.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(OperationButton_Click);

            btnMultiply.txtDigit.Text = "x";
            btnMultiply.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(OperationButton_Click);

            btnDivide.txtDigit.Text = "÷";
            btnDivide.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(OperationButton_Click);

            btnNegate.txtDigit.Text = "±";
            btnNegate.txtDigit.MouseLeftButtonDown += new MouseButtonEventHandler(NegateButton_Click);

            btnMinus.txtDigit.Tag = Enum.Parse(typeof(CalculatorOperation), "Subtract", false);
            btnPlus.txtDigit.Tag = Enum.Parse(typeof(CalculatorOperation), "Add", false);
            btnMultiply.txtDigit.Tag = Enum.Parse(typeof(CalculatorOperation), "Multiply", false);
            btnDivide.txtDigit.Tag = Enum.Parse(typeof(CalculatorOperation), "Divide", false);
        }        
	}
}